package com.whmall.service.crm.module.supplierchemical.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.whmall.component.entity.dto.PageRspDTO;
import com.whmall.service.crm.entity.dto.supplierchemical.*;
import com.whmall.service.crm.module.supplierchemical.dao.SupplierChemicalCoaMapper;
import com.whmall.service.crm.module.supplierchemical.dao.SupplierChemicalCoaRecordMapper;
import com.whmall.service.crm.module.supplierchemical.entity.SupplierChemicalCoaDO;
import com.whmall.service.crm.module.supplierchemical.entity.SupplierChemicalCoaRecordDO;
import com.whmall.service.crm.module.supplierchemical.entity.qo.SupplierChemicalCoaQO;
import com.whmall.service.crm.module.supplierchemical.service.SupplierChemicalCoaService;
import com.whmall.service.crm.module.supplierchemicalcoa.CoaSourceTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Description TODO
 * Author yangkuan
 * Date 2020/9/18 14:48
 **/
@Service
@Slf4j
public class SupplierChemicalCoaServiceImpl implements SupplierChemicalCoaService {

    @Autowired
    private SupplierChemicalCoaMapper supplierChemicalCoaMapper;

    @Autowired
    private SupplierChemicalCoaRecordMapper supplierChemicalCoaRecordMapper;

    @Autowired
    private ChemicalCoaInfoValidator chemicalCoaInfoValidator;

    @Override
    public PageRspDTO<SupplierChemicalCoaQueryRspDTO> queryAllCoaInfo(
            SupplierChemicalCoaQueryReqDTO supplierChemicalCoaQueryReqDTO) {

        PageRspDTO<SupplierChemicalCoaQueryRspDTO> result = new PageRspDTO<>();
        //  result.setRecords(companyRspDTOS);


        if (supplierChemicalCoaQueryReqDTO.getChemicalId() == null) {
            throw new IllegalArgumentException("化合物id不能为空");
        }
        if (supplierChemicalCoaQueryReqDTO.getPageNum() == null) {
            supplierChemicalCoaQueryReqDTO.setPageNum(1);
        }
        if (supplierChemicalCoaQueryReqDTO.getPageSize() == null) {
            supplierChemicalCoaQueryReqDTO.setPageSize(10);
        }
        supplierChemicalCoaQueryReqDTO.setOffset((supplierChemicalCoaQueryReqDTO.getPageNum() - 1)
                * (supplierChemicalCoaQueryReqDTO.getPageSize()));

        List<SupplierChemicalCoaQueryRspDTO> chemicalCoaRspDTOS = new ArrayList<>();
        //查询Coa基本信息
        List<SupplierChemicalCoaDO> supplierChemicalCoaDOS =
                supplierChemicalCoaMapper.selectByCreateDateAndCompanyIds(
                        supplierChemicalCoaQueryReqDTO);
        int count = supplierChemicalCoaMapper.selectCountByCreateDateAndCompanyIds(
                supplierChemicalCoaQueryReqDTO);
        result.setPageNum(supplierChemicalCoaQueryReqDTO.getPageNum());
        result.setPageSize(supplierChemicalCoaQueryReqDTO.getPageSize());
        result.setTotal(count);
        result.setCount((count / supplierChemicalCoaQueryReqDTO.getPageSize()) + 1);
        if (CollUtil.isEmpty(supplierChemicalCoaDOS)) {
            result.setRecords(chemicalCoaRspDTOS);
            return result;
        }

        List<Long> coaIds = new ArrayList<>();
        supplierChemicalCoaDOS.forEach(supplierChemicalCoaDO -> {
            SupplierChemicalCoaQueryRspDTO coaInfoRspDTO =
                    new SupplierChemicalCoaQueryRspDTO();
            coaIds.add(supplierChemicalCoaDO.getId());
            BeanUtils.copyProperties(supplierChemicalCoaDO, coaInfoRspDTO);
            coaInfoRspDTO.setChemicalCoaId(supplierChemicalCoaDO.getId());
            if (StrUtil.isNotEmpty(coaInfoRspDTO.getCoaUrl())
                    && coaInfoRspDTO.getCoaUrl().split("-").length >= 2){
                coaInfoRspDTO.setUrlName(coaInfoRspDTO.getCoaUrl().split("-")[1]);
            }else {
                coaInfoRspDTO.setUrlName("");
            }
            chemicalCoaRspDTOS.add(coaInfoRspDTO);
        });
        //查询供应商化合物COA记录信息
        List<SupplierChemicalCoaRecordDO> supplierChemicalCoaRecordDOS =
                supplierChemicalCoaRecordMapper.selectByCoaIds(coaIds);
        if (CollUtil.isEmpty(supplierChemicalCoaRecordDOS)) {
            result.setRecords(chemicalCoaRspDTOS);
            return result;
        }
        chemicalCoaRspDTOS.forEach(e -> {
            supplierChemicalCoaRecordDOS.forEach(supplierChemicalCoaRecordDO -> {
                if (supplierChemicalCoaRecordDO.getChemicalCoaId().longValue() == e.getChemicalCoaId().longValue()) {
                    ChemicalCoaRecordRspDTO chemicalCoaRecordRspDTO = new ChemicalCoaRecordRspDTO();
                    BeanUtils.copyProperties(supplierChemicalCoaRecordDO, chemicalCoaRecordRspDTO);
                    chemicalCoaRecordRspDTO.setChemicalCoaRecordId(supplierChemicalCoaRecordDO.getId());
                    if (e.getCoaRecordRspDTOS() == null) {
                        List<ChemicalCoaRecordRspDTO> coaRecordRspDTOS = new ArrayList<>();
                        e.setCoaRecordRspDTOS(coaRecordRspDTOS);
                    }
                    e.getCoaRecordRspDTOS().add(chemicalCoaRecordRspDTO);
                }
            });
        });
        result.setRecords(chemicalCoaRspDTOS);
        return result;
    }

    @Override
    public List<SupplierChemicalCoaQueryRspDTO> queryBy(SupplierChemicalCoaQueryByReqDTO reqDTO) {
        SupplierChemicalCoaQO qo = new SupplierChemicalCoaQO();
        BeanUtils.copyProperties(reqDTO, qo);
        return supplierChemicalCoaMapper.selectBy(qo)
                .stream().map(e -> {
                    SupplierChemicalCoaQueryRspDTO rspDTO = new SupplierChemicalCoaQueryRspDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    rspDTO.setChemicalCoaId(e.getId());
                    return rspDTO;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void chemicalCoaAdd(ChemicalCoaInfoReqDTO chemicalCoaInfoReqDTO) {

        Assert.notNull(chemicalCoaInfoReqDTO.getCompanyId(), "请求供应商ID不能为空");
        Assert.notNull(chemicalCoaInfoReqDTO.getUserId(), "请求供应商用户ID不能为空");
        Assert.notNull(chemicalCoaInfoReqDTO.getChemicalId(), "请求化合物ID不能为空");

        chemicalCoaInfoValidator.validate(chemicalCoaInfoReqDTO);
        SupplierChemicalCoaDO chemicalCoaDO = new SupplierChemicalCoaDO();
        //转换数据
        BeanUtils.copyProperties(chemicalCoaInfoReqDTO, chemicalCoaDO);
        //创建参数
        chemicalCoaDO.setCreateId(chemicalCoaInfoReqDTO.getEmployeeId());
        chemicalCoaDO.setCreateTime(new Date());
        //将其他的coa取消关联
        if (chemicalCoaInfoReqDTO.getCoaSourceType() != null &&
                chemicalCoaInfoReqDTO.getCoaSourceType().intValue() == CoaSourceTypeEnum.ORDER_DETAIL.getValue()){

            List<SupplierChemicalCoaDO> supplierChemicalCoaDOS = supplierChemicalCoaMapper
                    .selectBy(SupplierChemicalCoaQO.builder().coaSourceId(chemicalCoaInfoReqDTO.getCoaSourceId())
                            .coaSourceType(CoaSourceTypeEnum.ORDER_DETAIL.getValue()).build());

            if (CollUtil.isNotEmpty(supplierChemicalCoaDOS)){
                supplierChemicalCoaDOS.forEach(update -> {

                    update.setCoaSourceId(0L); /* 置零 */
                    update.setUpdateId(chemicalCoaInfoReqDTO.getEmployeeId());
                    update.setUpdateTime(new Date());
                    supplierChemicalCoaMapper.updateByPrimaryKeySelective(update);
                });
            }
        }

        supplierChemicalCoaMapper.insertSelective(chemicalCoaDO);

        List<ChemicalCoaRecordReqDTO> coaRecordReqDTOS = chemicalCoaInfoReqDTO.getCoaRecordReqs();

        List<SupplierChemicalCoaRecordDO> supplierChemicalCoaRecordDOS = new ArrayList<>();
        coaRecordReqDTOS.forEach(chemicalCoaRecordReqDTO -> {
            SupplierChemicalCoaRecordDO chemicalCoaRecordDO = new SupplierChemicalCoaRecordDO();
            BeanUtils.copyProperties(chemicalCoaRecordReqDTO, chemicalCoaRecordDO);
            chemicalCoaRecordDO.setChemicalCoaId(chemicalCoaDO.getId());
            //创建参数
            chemicalCoaRecordDO.setCreateId(chemicalCoaInfoReqDTO.getEmployeeId());
            chemicalCoaRecordDO.setCreateTime(new Date());
            chemicalCoaRecordDO.setUpdateId(chemicalCoaInfoReqDTO.getEmployeeId());
            chemicalCoaRecordDO.setUpdateTime(new Date());
            supplierChemicalCoaRecordDOS.add(chemicalCoaRecordDO);
        });

        supplierChemicalCoaRecordMapper.batchInsert(supplierChemicalCoaRecordDOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateChemicalCoa(ChemicalCoaInfoReqDTO chemicalCoaInfoReqDTO) {

        Assert.notNull(chemicalCoaInfoReqDTO.getChemicalCoaId(), "请求CoaID不能为空");
        Assert.notNull(chemicalCoaInfoReqDTO.getCompanyId(), "请求供应商ID不能为空");
        Assert.notNull(chemicalCoaInfoReqDTO.getUserId(), "请求供应商用户ID不能为空");
        Assert.notNull(chemicalCoaInfoReqDTO.getChemicalId(), "请求化合物ID不能为空");

        chemicalCoaInfoValidator.validate(chemicalCoaInfoReqDTO);
        SupplierChemicalCoaDO chemicalCoaDO = new SupplierChemicalCoaDO();
        //转换数据
        BeanUtils.copyProperties(chemicalCoaInfoReqDTO, chemicalCoaDO);

        chemicalCoaDO.setId(chemicalCoaInfoReqDTO.getChemicalCoaId());
        //更新参数
        chemicalCoaDO.setUpdateId(chemicalCoaInfoReqDTO.getEmployeeId());
        chemicalCoaDO.setUpdateTime(new Date());

        supplierChemicalCoaMapper.updateByPrimaryKeySelective(chemicalCoaDO);

        //需要移除coaRecordId
        List<Long> removeChemicalCoaRecordIds = new ArrayList<>();
        //查询出所有的coaRecordId
        List<Long> chemicalCoaRecordIds = new ArrayList<>();
        //请求参数中coaRecordId
        List<Long> coaRecordReqIds = new ArrayList<>();
        List<SupplierChemicalCoaRecordDO> supplierChemicalCoaRecords = supplierChemicalCoaRecordMapper
                .selectByChemicalCoaId(chemicalCoaInfoReqDTO.getChemicalCoaId());

        if (CollUtil.isNotEmpty(supplierChemicalCoaRecords)) {
            List<ChemicalCoaRecordReqDTO> coaRecordReqs = chemicalCoaInfoReqDTO.getCoaRecordReqs();
            supplierChemicalCoaRecords.forEach(e -> {
                chemicalCoaRecordIds.add(e.getId());
            });
            if (CollUtil.isNotEmpty(coaRecordReqs)) {

                coaRecordReqs.forEach(e -> {
                    if (e.getChemicalCoaRecordId() != null) {
                        coaRecordReqIds.add(e.getChemicalCoaRecordId());
                    }
                });
                //取差集
                removeChemicalCoaRecordIds = (List<Long>) CollUtil
                        .disjunction(chemicalCoaRecordIds, coaRecordReqIds);
            } else {
                //全部删除
                removeChemicalCoaRecordIds = chemicalCoaRecordIds;
            }
        }

        List<ChemicalCoaRecordReqDTO> coaRecordReqDTOS = chemicalCoaInfoReqDTO.getCoaRecordReqs();
        List<SupplierChemicalCoaRecordDO> supplierChemicalCoaRecordDOS = new ArrayList<>();
        coaRecordReqDTOS.forEach(chemicalCoaRecordReqDTO -> {
            if (chemicalCoaRecordReqDTO.getChemicalCoaRecordId() == null) {
                SupplierChemicalCoaRecordDO chemicalCoaRecordDO = new SupplierChemicalCoaRecordDO();
                BeanUtils.copyProperties(chemicalCoaRecordReqDTO, chemicalCoaRecordDO);
                chemicalCoaRecordDO.setChemicalCoaId(chemicalCoaDO.getId());
                //创建参数
                chemicalCoaRecordDO.setCreateId(chemicalCoaInfoReqDTO.getEmployeeId());
                chemicalCoaRecordDO.setCreateTime(new Date());
                chemicalCoaRecordDO.setUpdateId(chemicalCoaInfoReqDTO.getEmployeeId());
                chemicalCoaRecordDO.setUpdateTime(new Date());
                supplierChemicalCoaRecordDOS.add(chemicalCoaRecordDO);
            } else {
                List<SupplierChemicalCoaRecordDO> chemicalCoaRecordDOS = supplierChemicalCoaRecordMapper
                        .selectByChemicalCoaId(chemicalCoaDO.getId());
                chemicalCoaRecordDOS.forEach(supplierChemicalCoaRecordDO -> {
                    if (supplierChemicalCoaRecordDO.getId().longValue() == chemicalCoaRecordReqDTO.getChemicalCoaRecordId().longValue()) {
                        //转换数据
                        BeanUtils.copyProperties(chemicalCoaRecordReqDTO, supplierChemicalCoaRecordDO);
                        supplierChemicalCoaRecordDO.setChemicalCoaId(chemicalCoaDO.getId());
                        //更新参数
                        supplierChemicalCoaRecordDO.setUpdateId(chemicalCoaInfoReqDTO.getEmployeeId());
                        supplierChemicalCoaRecordDO.setUpdateTime(new Date());
                        supplierChemicalCoaRecordMapper.updateByPrimaryKeySelective(supplierChemicalCoaRecordDO);
                    }
                });
            }
        });
        //批量新增
        if (CollUtil.isNotEmpty(supplierChemicalCoaRecordDOS)) {
            supplierChemicalCoaRecordMapper.batchInsert(supplierChemicalCoaRecordDOS);
        }
        //批量移除
        if (CollUtil.isNotEmpty(removeChemicalCoaRecordIds)) {
            supplierChemicalCoaRecordMapper.removeByIds(removeChemicalCoaRecordIds);
        }
    }

    @Override
    public SupplierChemicalCoaQueryRspDTO queryCoaInfoById(Long chemicalCoaId) {

        Assert.notNull(chemicalCoaId, "请求coa Id不能为空");

        SupplierChemicalCoaDO supplierChemicalCoaDO = supplierChemicalCoaMapper
                .selectByPrimaryKey(chemicalCoaId);
        SupplierChemicalCoaQueryRspDTO chemicalCoaRspDTO = new SupplierChemicalCoaQueryRspDTO();
        if (supplierChemicalCoaDO == null) {
            return chemicalCoaRspDTO;
        }
        //转换数据
        BeanUtils.copyProperties(supplierChemicalCoaDO, chemicalCoaRspDTO);
        chemicalCoaRspDTO.setChemicalCoaId(supplierChemicalCoaDO.getId());

        List<SupplierChemicalCoaRecordDO> chemicalCoaRecordDOS = supplierChemicalCoaRecordMapper
                .selectByChemicalCoaId(chemicalCoaId);

        if (CollUtil.isEmpty(chemicalCoaRecordDOS)) {
            return chemicalCoaRspDTO;
        }
        chemicalCoaRecordDOS.forEach(supplierChemicalCoaRecordDO -> {
            ChemicalCoaRecordRspDTO chemicalCoaRecordRspDTO = new ChemicalCoaRecordRspDTO();
            BeanUtils.copyProperties(supplierChemicalCoaRecordDO, chemicalCoaRecordRspDTO);
            chemicalCoaRecordRspDTO.setChemicalCoaRecordId(supplierChemicalCoaRecordDO.getId());
            if (chemicalCoaRspDTO.getCoaRecordRspDTOS() == null) {
                List<ChemicalCoaRecordRspDTO> coaRecordRspDTOS = new ArrayList<>();
                chemicalCoaRspDTO.setCoaRecordRspDTOS(coaRecordRspDTOS);
            }
            chemicalCoaRspDTO.getCoaRecordRspDTOS().add(chemicalCoaRecordRspDTO);
        });
        return chemicalCoaRspDTO;
    }

    @Transactional
    @Override
    public void copyAsOrderDetailSource(Long requesterId, Long chemicalCoaId, Long orderDetailId, Integer cCoaSourceType) {
        Assert.notNull(requesterId, "请求者ID不能为空");
        Assert.notNull(chemicalCoaId, "化合物COA ID不能为空");
        Assert.notNull(orderDetailId, "订单明细ID不能为空");

        List<SupplierChemicalCoaDO> supplierChemicalCoaDOS = supplierChemicalCoaMapper
                .selectBy(SupplierChemicalCoaQO.builder().coaSourceId(orderDetailId)
                //.coaSourceType(CoaSourceTypeEnum.ORDER_DETAIL.getValue()).build());
                .coaSourceType(cCoaSourceType).build());
        //将其他的coa取消关联
        if (CollUtil.isNotEmpty(supplierChemicalCoaDOS)){
            supplierChemicalCoaDOS.forEach(update -> {

                update.setCoaSourceId(0L); /* 置零 */
                update.setUpdateId(requesterId);
                update.setUpdateTime(new Date());
                supplierChemicalCoaMapper.updateByPrimaryKeySelective(update);
            });
        }
        SupplierChemicalCoaDO coa = supplierChemicalCoaMapper.selectByPrimaryKey(chemicalCoaId);
        if (null == coa) {
            throw new IllegalArgumentException("供应商化合物COA不存在，ID：'" + chemicalCoaId + "'");
        }

        //
        // 修改来源
        coa.setCoaSourceType(cCoaSourceType);
        coa.setCoaSourceId(orderDetailId);

        //
        // 复制COA信息
        coa.setId(null);
        coa.setCreateId(requesterId);
        coa.setCreateTime(new Date());
        coa.setUpdateId(null);
        coa.setUpdateTime(null);
        supplierChemicalCoaMapper.insertSelective(coa);

        //
        // 复制COA记录信息
        supplierChemicalCoaRecordMapper.selectByChemicalCoaId(chemicalCoaId)
                .stream()
                .peek(e -> {
                    e.setId(null);
                    e.setChemicalCoaId(coa.getId());
                    e.setCreateId(requesterId);
                    e.setCreateTime(new Date());
                    e.setUpdateId(null);
                    e.setUpdateTime(null);
                })
                .forEach(supplierChemicalCoaRecordMapper::insertSelective);
    }

    @Transactional
    @Override
    public void resetSourceId(Long requesterId, Long chemicalCoaId) {
        Assert.notNull(requesterId, "请求者ID不能为空");
        Assert.notNull(chemicalCoaId, "化合物COA ID不能为空");

        SupplierChemicalCoaDO update = new SupplierChemicalCoaDO();
        update.setId(chemicalCoaId);
        update.setCoaSourceId(0L); /* 置零 */
        update.setUpdateId(requesterId);
        update.setUpdateTime(new Date());
        supplierChemicalCoaMapper.updateByPrimaryKeySelective(update);
    }

    @Override
    public void settingFields(Long requesterId, Long chemicalCoaId, ChemicalCoaInfoReqDTO onlyNonNullFeilds) {
        Assert.notNull(requesterId, "请求者ID不能为空");
        Assert.notNull(chemicalCoaId, "化合物COA ID不能为空");

        SupplierChemicalCoaDO update = new SupplierChemicalCoaDO();

        BeanUtils.copyProperties(onlyNonNullFeilds, update);

        update.setId(chemicalCoaId);
        update.setUpdateId(requesterId);
        update.setUpdateTime(new Date());
        supplierChemicalCoaMapper.updateByPrimaryKeySelective(update);
    }
}
